package com.niodata.dp.monitor.components.task;

import com.niodata.dp.core.DpConfiguration;
import com.niodata.dp.monitor.components.task.monitor.AddExpectExecTimeJob;
import com.niodata.dp.monitor.components.task.monitor.CheckExecutionsInDbJob;
import com.niodata.dp.monitor.components.task.monitor.CheckNotFoundJob;
import com.niodata.dp.monitor.components.task.monitor.CheckStatusJob;
import com.niodata.dp.monitor.components.task.monitor.HistoryFetchJob;
import com.niodata.dp.monitor.components.task.monitor.TaskExecCountJob;
import com.niodata.dp.monitor.components.task.monitor.TaskExecFailedCountJob;
import com.niodata.dp.monitor.components.task.monitor.TaskExecHourCountJob;
import com.niodata.dp.monitor.core.task.TaskExecutionManager;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

/**
 * Created by ndp on 17-7-13.
 */
@Component
public class TaskMonitorListener implements ApplicationListener<ContextRefreshedEvent> {

  public static final String TASK_MONITOR_GROUP = "task_monitor_group";

  private Logger logger = LoggerFactory.getLogger(getClass());
  @Autowired
  private Scheduler scheduler;
  @Autowired
  @Qualifier("taskManagerImpl")
  private TaskExecutionManager taskManager;

  private boolean enabled =
        DpConfiguration.getBoolean("monitor.task.enabled", true);

  @Override
  public void onApplicationEvent(ContextRefreshedEvent event) {
    if (!enabled) {
      return;
    }
    JobDetail histJob = JobBuilder.newJob(HistoryFetchJob.class)
          .withIdentity("histFetchJob", TASK_MONITOR_GROUP)
          .build();
    CronTrigger trigger = TriggerBuilder.newTrigger()
          .withIdentity("histFetchTrigger", TASK_MONITOR_GROUP)
          .withSchedule(CronScheduleBuilder.cronSchedule("*/20 * * * * ?"))
          .build();
    try {
      scheduler.scheduleJob(histJob, trigger);

      JobDetail checkStatusJob = JobBuilder.newJob(CheckStatusJob.class)
            .withIdentity("checkStatusJob", TASK_MONITOR_GROUP)
            .build();
      CronTrigger checkStatusTrigger = TriggerBuilder.newTrigger()
            .withIdentity("checkStatusTrigger", TASK_MONITOR_GROUP)
            .withSchedule(CronScheduleBuilder.cronSchedule("*/40 * * * * ?"))
            .build();
      scheduler.scheduleJob(checkStatusJob, checkStatusTrigger);

      JobDetail checkAllStatusInDb = JobBuilder.newJob(CheckExecutionsInDbJob.class)
            .withIdentity("checkStatusInDb", TASK_MONITOR_GROUP)
            .build();
      CronTrigger checkInDbTrigger = TriggerBuilder.newTrigger()
            .withIdentity("checkInDbTrigger", TASK_MONITOR_GROUP)
            .withSchedule(CronScheduleBuilder.cronSchedule("40 0/15 * * * ?"))
            .build();
      scheduler.scheduleJob(checkAllStatusInDb, checkInDbTrigger);

      //小时执行次数统计
      JobDetail taskExecHourCountJob = JobBuilder.newJob(TaskExecHourCountJob.class)
            .withIdentity("taskExecHourCountJob", TASK_MONITOR_GROUP)
            .build();
      CronTrigger taskExecHourCountTrigger = TriggerBuilder.newTrigger()
            .withIdentity("taskExecHourCountTrigger", TASK_MONITOR_GROUP)
            //.withSchedule(CronScheduleBuilder.cronSchedule("0 0 1 * * ?"))
            .withSchedule(CronScheduleBuilder.cronSchedule("0 1 */1 * * ?"))
            .build();
      scheduler.scheduleJob(taskExecHourCountJob, taskExecHourCountTrigger);

      //日执行次数统计
      JobDetail taskExecCountJob = JobBuilder.newJob(TaskExecCountJob.class)
            .withIdentity("taskExecCountJob", TASK_MONITOR_GROUP)
            .build();
      CronTrigger taskExecCountTrigger = TriggerBuilder.newTrigger()
            .withIdentity("taskExecCountTrigger", TASK_MONITOR_GROUP)
            .withSchedule(CronScheduleBuilder.cronSchedule("0 0 1 * * ?"))
            .build();

      scheduler.scheduleJob(taskExecCountJob, taskExecCountTrigger);

      //失败任务统计
      JobDetail taskFailedCountJob = JobBuilder.newJob(TaskExecFailedCountJob.class)
            .withIdentity("taskFailedCountJob", TASK_MONITOR_GROUP)
            .build();
      CronTrigger taskFailedCountTrigger = TriggerBuilder.newTrigger()
            .withIdentity("taskFailedCountTrigger", TASK_MONITOR_GROUP)
            .withSchedule(CronScheduleBuilder.cronSchedule("0 1 */1 * * ?"))
            .build();
      scheduler.scheduleJob(taskFailedCountJob, taskFailedCountTrigger);

      //添加期望执行序列 AddExpectExecTimeJob

      //CheckNotFoundJob
      JobDetail checkNotFoundJob = JobBuilder.newJob(CheckNotFoundJob.class)
            .withIdentity("checkNotFoundJob", TASK_MONITOR_GROUP)
            .build();
      CronTrigger checkNotFoundTrigger = TriggerBuilder.newTrigger()
            .withIdentity("checkNotFoundTrigger", TASK_MONITOR_GROUP)
            .withSchedule(CronScheduleBuilder.cronSchedule("50 * * * * ?"))
            .build();
      scheduler.scheduleJob(checkNotFoundJob, checkNotFoundTrigger);

      //AddExpectExecTimeJob
      JobDetail addExpectExecTimeJob = JobBuilder.newJob(AddExpectExecTimeJob.class)
            .withIdentity("AddExpectExecTimeJob", TASK_MONITOR_GROUP)
            .build();
      CronTrigger addExpectExecTimeTrigger = TriggerBuilder.newTrigger()
            .withIdentity("addExpectExecTimeTrigger", TASK_MONITOR_GROUP)
            .withSchedule(CronScheduleBuilder.cronSchedule("0 */10 * * * ?"))
            .build();
      scheduler.scheduleJob(addExpectExecTimeJob, addExpectExecTimeTrigger);

      logger.info("Task Monitor Started");
    } catch (Exception e) {
      throw new RuntimeException("TaskMonitor StartError", e);
    }
  }
}
